当前位置:  开发笔记 > 后端 > 正文

`Array#each_slice`,在开头留下余数

如何解决《`Array#each_slice`,在开头留下余数》经验,为你挑选了2个好方法。

我正在尝试将数组切成三组.我希望在开头有余数([1, 2]在下面的例子中).

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
...
#=> [[1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

有一个很好的方法来做到这一点?

拆分数组的通常方法是:

arr.each_slice(3)
# => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]

这样就[10, 11]可以在最后得到余数.我尝试如下,思考each_slice可能会接受一个负面的论点并将其读作在数组中向后移动.

arr.each_slice(-3)

唉,它没用.



1> Aleksei Mati..:

虽然有人可能会将数组反转三次,但实现目标的方法更为有效:

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a = arr.dup # not to modify it inplace
[a.shift(a.size % 3)] + a.each_slice(3).to_a
#? [[1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

BTW,arr.each_slice(3)返回一个枚举器,而不是你在问题中发布的数组.

如Cary Swoveland所建议的更新或无效dup:

n = a.size % 3
[a[0...n]] + a[n..-1].each_slice(3).to_a

UPD摆脱dup由@sawa:

[a.first(a.size % 3)] + a.drop(a.size % 3).each_slice(3).to_a

UPD只是出于好奇(假设输入没有nil元素):

([nil] * (3 - a.size % 3) + a).each_slice(3).to_a.tap do |a|
  a.unshift(a.shift.compact!)
end

以上可能安全地在原始数组上运行,它不会在原地修改它.

正如Stefan在评论中所指出的UPD2,如果数组可以被3整除,上面的任何一个都会产生一个初始的空切片.所以,正确的解决方案(和,最快的,顺便说一句)应该是这样的:

(arr.size % 3).zero? ? arr.each_slice(3).to_a : ANY_OF_THE_ABOVE



2> shivam..:

一个简单的组合reverseeach_slice将要做的诀窍:

arr.reverse.each_slice(3).map(&:reverse).reverse
#=> [[1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

说明:

我正在逆转阵列并做each_slice.这会给我:

[[11, 10, 9], [8, 7, 6], [5, 4, 3], [2, 1]]

现在我正在迭代这个并反转每个子数组以匹配预期的子数组序列.map(&:reverse).最后我正在反转整个数组以获得所需的序列(最后一个.reverse).


这读得很好,应该很快.你可以通过用`reverse_each`替换第一个`reverse`来消除一个数组.
推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有